// Dependencies:
// * http://jquery.com/
// * https://github.com/mondalaci/positional-format.js
// $ bower install jquery positional-format.js

/**
 * Convert DXF string to SVG format.
 * @param {string} dxfString The DXF string to be converted.
 * @returns {string|null} The converted SVG string or null if the conversion was unsuccessful.
 */

function dxfToSvg(dxfString)
{
    "use strict";
	
    function dxfObjectToSvgSnippet(dxfObject)
    {
        function getLineSvg(x1, y1, x2, y2)
        {
            return '<path d="M{0},{1} {2},{3}"/>\n'.format(x1, y1, x2, y2);
        }

        function deg2rad(deg)
        {
            return deg * (Math.PI/180);
        }

        switch (dxfObject.type) {
            case 'LINE':
                return getLineSvg(dxfObject.x, dxfObject.y, dxfObject.x1, dxfObject.y1);
            case 'CIRCLE':
                return '<circle cx="{0}" cy="{1}" r="{2}"/>\n'.format(dxfObject.x, dxfObject.y, dxfObject.r);
            case 'ARC':
                var x1 = dxfObject.x + dxfObject.r * Math.cos(deg2rad(dxfObject.a0));
                var y1 = dxfObject.y + dxfObject.r * Math.sin(deg2rad(dxfObject.a0));
                var x2 = dxfObject.x + dxfObject.r * Math.cos(deg2rad(dxfObject.a1));
                var y2 = dxfObject.y + dxfObject.r * Math.sin(deg2rad(dxfObject.a1));

                if (dxfObject.a1 < dxfObject.a0) {
                    dxfObject.a1 += 360;
                }
                var largeArcFlag = dxfObject.a1 - dxfObject.a0 > 180 ? 1 : 0;

                return '<path d="M{0},{1} A{2},{3} 0 {4},1 {5},{6}"/>\n'.
                        format(x1, y1, dxfObject.r, dxfObject.r, largeArcFlag, x2, y2);
            case 'LWPOLYLINE':
                var svgSnippet = '';
                var vertices = dxfObject.vertices;
                for (var i=0; i<vertices.length-1; i++) {
                    var vertice1 = vertices[i];
                    var vertice2 = vertices[i+1];
                    svgSnippet += getLineSvg(vertice1.x, vertice1.y, vertice2.x, vertice2.y);
                }
                return svgSnippet;
        }
    }

    var groupCodes = {
        0: 'entityType',
        2: 'name',
		8: 'layerName',
        10: 'x',
        11: 'x1',
        20: 'y',
        21: 'y1',
        40: 'r', // Radius
        50: 'a0', // Arc start angle
        51: 'a1'// Arc end angle
    };

    var supportedEntities = [
        'LINE',
        'CIRCLE',
        'ARC',
        'LWPOLYLINE'
    ];

    var counter = 0;
    var code = null;
	var isLayerSectionActive = false;
    var isEntitiesSectionActive = false;
    var currentLayer = null;
	var layers = [];
    var object = {};
	
    

    // Normalize platform-specific newlines.
    dxfString = dxfString.replace(/\r\n/g, '\n');
    dxfString = dxfString.replace(/\r/g, '\n');

    dxfString.split('\n').forEach(function(line) {
        line = line.trim();

        if (counter++ % 2 === 0) {
            code = parseInt(line);
        } else {
            var value = line;
            var groupCode = groupCodes[code];
			
			//Start looking for layers to store
			if(groupCode === 'name' && value === 'LAYER'){
				isLayerSectionActive = true;
			}
			
			// Store create and store new layers from DXF layer table 
			if(isLayerSectionActive){
                if(groupCode === 'name' && 
                value !== 'LAYER' && 
                value !== 'DEFPOINTS' &&
                value !== 'Defpoints'){ // So it can skip table name and defpoints layer
                
                    var newLayer = {};
                        newLayer.name = value;
						newLayer.isVisible = true;    
						newLayer.paths = '';
	
                    layers.push(newLayer);
				}
				
				if(groupCode === 'entityType' && value === 'ENDTAB'){
					isLayerSectionActive = false;
				}
			}
			
			//Start looking for drawable entities
            if (groupCode === 'name' && value === 'ENTITIES') {  
                isEntitiesSectionActive = true;
            } 
		

            if(groupCode === 'layerName'){
                currentLayer = value;
            }
			
			if (isEntitiesSectionActive) {
                if (groupCode === 'entityType') {  // New entity starts.
                    if (object.type) {
                        object.layerName = currentLayer;
                        
                        for(var i = 0; i<layers.length; i++){
                          if(layers[i].name === currentLayer){
							 layers[i].paths += dxfObjectToSvgSnippet(object);
                             
                          }
                      }
    
                    }
				
                    object = $.inArray(value, supportedEntities) > -1 ? {type: value} : {};
					
                    if (value === 'ENDSEC') {
                        isEntitiesSectionActive = false;
                    }
                } else if (object.type && typeof groupCode !== 'undefined') {  // Known entity property recognized.
                    object[groupCode] = parseFloat(value);

                    if (object.type == 'LWPOLYLINE' && groupCode === 'y') {
                        if (!object.vertices) {
                            object.vertices = [];
                        }
                        object.vertices.push({x:object.x, y:object.y});
						
                    }
                }
            }
        }
    });

	return layers;

}